
class Model(object):

    def __init__(self, game_state):
        self.__game_state = game_state
        self.__game_state.add_listener(self)
        self.__move_history_list = []

    def __create_state_list(self, possible_state_list):
        state_list = []
        for i, player in enumerate(self.__game_state.get_player_list()):
            if len(state_list) == 0:
                for player_state in possible_state_list[i]:
                    state_list.append([player_state])
            else:
                tmp_state_list = []
                for x, state in enumerate(state_list):
                    for player_state in possible_state_list[i]:
                        tmp_state = list(state)
                        tmp_state.append(player_state)
                        tmp_state_list.append(tmp_state)
                state_list = tmp_state_list
        return state_list


    def get_model_description(self):
        model = {}
        model["state_list"] = ["asdf", "asdf"]
        model["transition_list"] = []

        possible_state_list = []
        for player in self.__game_state.get_player_list():
            possible_state_list.append([])
        #calculate possible stones of each player:
        for i, player in enumerate(self.__game_state.get_player_list()):
            #TODO: only works for 2 stones:
            stones = self.__game_state.get_stone_list()[i]
            nr_stones = stones["black"] + stones["white"]
            if nr_stones > 1:
                print possible_state_list
                possible_state_list[i].append("bw%d" % i)
            else:
                possible_state_list[i].append("b%d" % i)
                possible_state_list[i].append("w%d" % i)

        #create all possible states:
        state_list = self.__create_state_list(possible_state_list)

        #convert state_list to strings:
        label_state_list = []
        for state in state_list:
            label = ""
            for val in state:
                label += val
            label_state_list.append(label)
        model["state_list"] = label_state_list

        #draw transitions for all agents without swapping:
        transition_list = []
        for i, player in enumerate(self.__game_state.get_player_list()):
            #bin connected states:
            connected_state_list_list = []
            for possible_state in possible_state_list[i]:
                connected_state_list = []
                for s, state in enumerate(state_list):
                    if state[i] == possible_state:
                        connected_state_list.append(s)
                connected_state_list_list.append(connected_state_list)
            #convert to transitions:
            print connected_state_list_list
            for connected_state_list in connected_state_list_list:
                for x, state in enumerate(connected_state_list):
                    for y in range(x, len(connected_state_list)):
                        transition_list.append((state, connected_state_list[y], i))

        #determin which knowledge is shared:
        shared_knowledge_list = []
        for player in self.__game_state.get_player_list():
            shared_knowledge_list.append([])
        print "COUNT:"
        print self.__move_history_list
        for move in self.__move_history_list:
            if not move["swap"] == -1:
                shared_knowledge_list[move["player"]].append(move["swap"])
                shared_knowledge_list[move["swap"]].append(move["player"])

        #remove transitions that are not possible due to swapping:
        remove_transition_index_set = set()
        for i, player in enumerate(self.__game_state.get_player_list()):
            for t, transition in enumerate(transition_list):
                if transition[2] == i:
                    from_state = transition[0]
                    end_state = transition[1]
                    for shared_player in shared_knowledge_list[i]:
                        if not state_list[from_state][shared_player] == state_list[end_state][shared_player]:
                            remove_transition_index_set.add(t)
        final_transition_list = []
        for t, transition in enumerate(transition_list):
            if not t in remove_transition_index_set:
                final_transition_list.append(transition)

        model["transition_list"] = final_transition_list

        return model


    def event_move(self, move):
        """Executed after a move is made."""
        move["player"] = self.__game_state.get_next_player()
        self.__move_history_list.append(move.copy())